package com.apobates.jforum.grief.schema2doc.core.schema;

import java.util.Optional;

/**
 * RDBMS数据方言
 */
public enum SchemaDialect {
    MySQL("mysql"){
        @Override
        public String buildJdbcURL(String url, String database, String schema) {
            // ://dev.mysql.com/doc/connector-j/8.1/en/connector-j-reference-jdbc-url-format.html
            // protocol//[hosts][/database][?properties]
            return url;
        }

        @Override
        public void validate(Optional<String> database, Optional<String> schema) throws IllegalArgumentException {
            if(!database.isPresent()){
                throw new IllegalArgumentException("[MySQL]缺少数据库名称");
            }
        }
    }, Oracle("oracle"){
        @Override
        public String buildJdbcURL(String url, String database, String schema) {
            // ://docs.oracle.com/en/middleware/bi/analytics-server/administer-publisher-oas/set-jdbc-connection-data-source.html#GUID-FB2AEC3B-2178-48DF-8B9F-76ED2D6B5194
            // jdbc:oracle:thin:@[host]:[port]:[sid] 通过SID连接
            // jdbc:oracle:thin:@//<host>[:<port>]/<service_name> 通过ServiceName连接
            return url.concat("?oracle.jdbc.defaultSchema=").concat(schema);
        }

        @Override
        public void validate(Optional<String> database, Optional<String> schema) throws IllegalArgumentException {
            if(!schema.isPresent()){
                throw new IllegalArgumentException("[Oracle]缺少模式名称");
            }
        }
    }, SQLServer("mssql"){
        @Override
        public String buildJdbcURL(String url, String database, String schema) {
            // ://learn.microsoft.com/en-us/sql/connect/jdbc/building-the-connection-url?view=sql-server-ver16
            // jdbc:sqlserver://[serverName[\instanceName][:portNumber]][;property=value[;property=value]]
            return url.contains(database) ? url : url.concat(";databaseName="+database);
        }

        @Override
        public void validate(Optional<String> database, Optional<String> schema) throws IllegalArgumentException {
            if(!database.isPresent()){
                throw new IllegalArgumentException("[SQLServer]缺少数据库名称");
            }
        }
    }, PostgreSQL("postgresql"){
        @Override
        public String buildJdbcURL(String url, String database, String schema) {
            // ://jdbc.postgresql.org/documentation/use/
            // jdbc:postgresql://<hostname>:<port>/<database>?currentSchema=<schema_name>
            return url.concat("/"+database).concat("?currentSchema=").concat(schema);
        }

        @Override
        public void validate(Optional<String> database, Optional<String> schema) throws IllegalArgumentException {
            if(!database.isPresent() || !schema.isPresent()){
                throw new IllegalArgumentException("[PostgreSQL]缺少数据库名称或模式名称");
            }
        }
    }, MariaDB("mariadb"){
        @Override
        public String buildJdbcURL(String url, String database, String schema) {
            // https://mariadb.com/kb/en/about-mariadb-connector-j/
            // jdbc:mariadb:[replication:|loadbalance:|sequential:]//<hostDescription>[,<hostDescription>...]/[database][?<key1>=<value1>[&<key2>=<value2>]]
            return url;
        }

        @Override
        public void validate(Optional<String> database, Optional<String> schema) throws IllegalArgumentException {
            if(!database.isPresent()){
                throw new IllegalArgumentException("[MariaDB]缺少数据库名称");
            }
        }
    }, SQLite("sqlite"){
        @Override
        public String buildJdbcURL(String url, String database, String schema) {
            // https://www.sqlitetutorial.net/sqlite-java/sqlite-jdbc-driver/
            // jdbc:sqlite:sqlite_database_file_path
            return url;
        }

        @Override
        public void validate(Optional<String> database, Optional<String> schema) throws IllegalArgumentException {

        }
    }, Informix("informix"){
        @Override
        public String buildJdbcURL(String url, String database, String serviceName) {
            // https://www.ibm.com/docs/en/informix-servers/12.10?topic=database-drivermanagergetconnection-method
            // jdbc:informix-sqli://123.45.67.89:1533/testDB:INFORMIXSERVER=myserver;user=rdtest;password=test
            return url.concat("/").concat(database).concat(":INFORMIXSERVER=").concat(serviceName);
        }

        @Override
        public void validate(Optional<String> database, Optional<String> server) throws IllegalArgumentException {
            if(!database.isPresent() || !server.isPresent()){
                throw new IllegalArgumentException("[Informix]缺少数据库名称或服务名称");
            }
        }
    },Sybase("sybase"){
        @Override
        public String buildJdbcURL(String url, String database, String schema) {
            // https://docs.oracle.com/cd/E13222_01/wls/docs103/jdbc_drivers/sybase.html#wp1068326
            // jdbc:bea:sybase://hostname:port[;property=value[;...]]
            return url;
        }

        @Override
        public void validate(Optional<String> database, Optional<String> schema) throws IllegalArgumentException {

        }
    }, ETC("etc"){
        @Override
        public String buildJdbcURL(String url, String database, String schema) {
            throw new UnsupportedOperationException("未确认的数据方言");
        }

        @Override
        public void validate(Optional<String> database, Optional<String> schema) throws IllegalArgumentException {

        }
    };

    private final String name;

    SchemaDialect(String name) {
        this.name = name;
    }

    public abstract String buildJdbcURL(String url, String database, String schema);

    public abstract void validate(Optional<String> database, Optional<String> schema) throws IllegalArgumentException;
}
